package Screens 
{
	import DeviceData.LocalDB;
	import feathers.controls.Button;
	import feathers.controls.ButtonGroup;
	import feathers.controls.Header;
	import feathers.controls.ImageLoader;
	import feathers.controls.Label;
	import feathers.controls.Screen;
	import feathers.controls.ScrollContainer;
	import feathers.controls.Scroller;
	import feathers.controls.TextInput;
	import feathers.data.ListCollection;
	import feathers.events.FeathersEventType;
	import feathers.layout.HorizontalLayout;
	import feathers.layout.VerticalLayout;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.PixelSnapping;
	import flash.display.Shape;
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
	import flash.events.TouchEvent;
	import flash.filesystem.File;
	import flash.geom.Matrix;
	import flash.text.TextFormat;
	import Media.ExtendedMetalWorksMobileTheme;
	import starling.display.DisplayObject;
	import starling.display.Image;
	import starling.display.MovieClip;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.textures.Texture;
	
	/**
	 * @author Simon Claeye
	 * @version 2.0
	 */
	public class InfoScreen extends Screen
	{
		//util
		private var database:LocalDB;
		private var capture:CaptureScreen;
		
		//Containers
		private var container:ScrollContainer;
		private var innerContainer:ScrollContainer;
		
		//input fields
		private var notesIn:TextInput;
		private var tagsIn:TextInput;
		private var initialized:Boolean = false;
		
		/*
		 * Local database is passed as a paramater in order to take advantage of the prepared statemtents.
		 */
		public function InfoScreen(capture:CaptureScreen=null, database:LocalDB=null) 
		{
			//inital setup
			this.database = database;
			this.capture = capture;
			
			this.addEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );
		}
		
		private function addedToStageHandler(event:Event):void
		{
			// handles the back and menu hardware keys on android
			this.backButtonHandler = backHandler;
			this.menuButtonHandler = menuHandler;
			
			var layout:VerticalLayout = new VerticalLayout();
			layout.gap = 20;
			layout.paddingLeft = (this.stage.stageWidth / 12);
			layout.paddingTop = (this.stage.stageHeight / 10);
			layout.paddingBottom = (this.stage.stageHeight / 10);
			layout.hasVariableItemDimensions = true;
			
			this.container = new ScrollContainer();
			container.layout = layout;
			container.scrollerProperties.horizontalScrollPolicy = Scroller.SCROLL_POLICY_OFF;
			container.scrollerProperties.verticalScrollPolicy = Scroller.SCROLL_POLICY_AUTO;
			container.scrollerProperties.snapScrollPositionsToPixels = true;
			container.setSize(this.stage.stageWidth, this.stage.stageHeight);
			addChild(container);
			
			//Draw header bar
			var header:Header = new Header();
			this.addChild(header);
			
			var backButton:Button = new Button();
			backButton.label = "Main Menu";
			backButton.addEventListener(Event.TRIGGERED, backHandler);
			
			//add back button to header
			header.leftItems = new <DisplayObject>[ backButton ];
			header.setSize((this.stage.stageWidth), (this.stage.stageHeight / 10));
			header.validate();			
			
			//drawAddInfo();
			drawImage();			
			drawInputFields();
		}		
		
		/**
		 * A function to dispatch an event when the back hardware key
		 * is pressed on android.
		 */
		private function backHandler():void
		{
			//cleanup
			if (this.container != null)
			{
				this.removeChild(container);
				this.container = null;
			}

			dispatchEvent(new NavigationEvent(NavigationEvent.RETURN));
		}
		
		/**
		 * A function to dispatch an event when the menu hardware key
		 * is pressed.
		 */
		private function menuHandler():void
		{
			dispatchEvent(new NavigationEvent(NavigationEvent.MAIN_MENU));
		}
		
		/**
		 * Draws the input fields and the buttons for the screen.
		 */
		private function drawInputFields():void
		{	
			//Tags
			var tagsLabel:Label = new Label();
			tagsLabel.text = "Tags (comma seperated):";
			tagsLabel.nameList.add(ExtendedMetalWorksMobileTheme.INPUT_LABEL);
			container.addChild(tagsLabel);
			
			this.tagsIn = new TextInput();
			tagsIn.setSize(10*(this.stage.stageWidth / 12), 1*(this.stage.stageHeight / 12));
			container.addChild(tagsIn);
			
			//Notes
			var notesLabel:Label = new Label();
			notesLabel.text = "Notes:";
			notesLabel.nameList.add(ExtendedMetalWorksMobileTheme.INPUT_LABEL);
			container.addChild(notesLabel);
			
			this.notesIn = new TextInput();
			notesIn.setSize(10*(this.stage.stageWidth / 12), 4*(this.stage.stageHeight / 12));
			container.addChild(notesIn);
			
			var group:ButtonGroup = new ButtonGroup();
			group.dataProvider = new ListCollection(
			[
				{ label: "Save", triggered: saveHandler },
				{ label: "Discard", triggered: discardHandler },
			]);
			group.direction = ButtonGroup.DIRECTION_HORIZONTAL;
			group.gap = 5;
			
			container.addChild(group);
		}
		
		/**
		 * Draws the image taken by the phone's camera.
		 */
		private function drawImage():void
		{
			var imgLoader:Loader = capture.getImage();
			var loadedBitmap:Bitmap = imgLoader.content as Bitmap;
			var image:Image = new Image(Texture.fromBitmap(resizeImage(loadedBitmap)));
			var imageSprite:Sprite = new Sprite();
			container.addChild(imageSprite);
			imageSprite.addChild(image);
		}
		
		/**
		 * Helper funtion to resize camera images so that they do not exceed the maximum
		 * size of textures.
		 * @param	image the images to be resized
		 * @return returns the resized bitmap
		 */
		private function resizeImage(image:Bitmap):Bitmap
		{
			var bigBMD:BitmapData = image.bitmapData;
			var size:int = 10 * (this.stage.stageWidth / 12);
			var scale:Number = Math.max(size / bigBMD.width, size / bigBMD.height);
			var matrix:Matrix = new Matrix();
			matrix.scale(scale, scale);

			var smallBMD:BitmapData = new BitmapData(bigBMD.width * scale, bigBMD.height * scale, true, 0x000000);
			smallBMD.draw(bigBMD, matrix, null, null, null, true);
			
			return new Bitmap(smallBMD, PixelSnapping.NEVER, true);
		}
		
		/**
		 * Saves or updates the data associated with the image dependin on what mode
		 * the screen is operating in.
		 */
		private function saveData():void
		{
			var nullValue:Number = null;	//to keep compiler from issueing warnings
				
			if (capture.hasGEOData())
			{
				database.writeImageData(capture.getImageNativePath(), capture.getGeoData().latitude, capture.getGeoData().longitude,
				capture.getGeoData().altitude, capture.getGeoData().horizontalAccuracy, capture.getGeoData().verticalAccuracy, nullValue, notesIn.text);
			}
			else
				database.writeImageData(capture.getImageNativePath(), nullValue, nullValue, nullValue, nullValue, nullValue, nullValue, notesIn.text);

			var tags:Array = tagsIn.text.split(",");
			for (var i:int = 0; i < tags.length; i++)
				database.writeTagData(capture.getImageNativePath(), tags[i]);
		}
		
		/**
		 * Function to handle the saving of the data to the local database.
		 * @param	event
		 */
		private function saveHandler(event:Event):void
		{
			//Save data into local DB until upload
			saveData();
			
			//cleanup
			this.removeChild(container);
			this.container = null;
			
			//Return to main menu
			dispatchEvent(new NavigationEvent(NavigationEvent.RETURN));
		}
		
		private function discardHandler(event:Event):void
		{
			//cleanup
			this.removeChild(container);
			this.container = null;
			
			dispatchEvent(new NavigationEvent(NavigationEvent.RETURN));
		}
	}
}